import 'package:family_expense/features/income_expense_detail_type/models/income_expense_detail_type.dart';
import 'package:family_expense/features/income_expense_detail_type/services/income_expense_detail_type_service.dart';
import 'package:family_expense/features/income_expense_detail_type/widgets/edit_income_expense_detail_type.dart';
import 'package:family_expense/shared/widgets/action_log.dart';
import 'package:flutter/material.dart';
import 'package:material_design_icons_flutter/material_design_icons_flutter.dart';
import 'package:my_flutter_core/my_flutter_core.dart';

/// It returns [dynamic] as navigation popping result.
///
/// It returns instance of [IncomeExpenseDetailType] that means it has been updated.
/// It returns [String] of the id that means it has been deleted.
class IncomeExpenseDetailTypeInfo extends StatefulWidget {
  const IncomeExpenseDetailTypeInfo(this.detailType, {super.key});

  final IncomeExpenseDetailType? detailType;

  @override
  State<IncomeExpenseDetailTypeInfo> createState() =>
      _IncomeExpenseDetailTypeInfoState();
}

class _IncomeExpenseDetailTypeInfoState
    extends State<IncomeExpenseDetailTypeInfo> {
  // For deleting data.
  final IncomeExpenseDetailTypeService _detailTypeService =
      IncomeExpenseDetailTypeService();

  // The updated data passed from [EditIncomeExpenseDetailType] and will be updated back to list.
  IncomeExpenseDetailType? _updatedDetailType;

  // Current authenticated user.
  User? _user;

  // The detail type for display.
  late IncomeExpenseDetailType? _detailType = widget.detailType!.clone();

  @override
  void initState() {
    super.initState();

    _getCurrentUser();
  }

  @override
  Widget build(BuildContext context) {
    return PopScope(
      canPop: false,
      onPopInvokedWithResult: _onPopInvokedWithResult,
      child: Scaffold(appBar: _buildAppBar(), body: _buildBody()),
    );
  }

  /// Builds app bar.
  PreferredSizeWidget _buildAppBar() {
    return AppBar(
      title: const Text('类别详情'),
      actions: <Widget>[
        if (_user?.isAccountGroupAdmin == true)
          IconButton(
            icon: const Icon(Icons.delete),
            tooltip: '删除',
            onPressed: _delete,
          ),
        if (_user?.isAccountGroupAdmin == true)
          IconButton(
            icon: Icon(MdiIcons.squareEditOutline),
            tooltip: '修改',
            onPressed: _gotoUpdateView,
          ),
      ],
    );
  }

  /// Builds the list view to display the details.
  Widget _buildBody() {
    if (widget.detailType == null) {
      return const MyPageTopCenterLoadingIndicator();
    }

    return ListView(
      padding: const EdgeInsets.all(10.0),
      children: [
        ListTile(title: const Text('名称'), trailing: Text(_detailType!.name!)),
        ListTile(title: const Text('标题'), trailing: Text(_detailType!.title!)),
        ListTile(
          title: const Text('子标题'),
          trailing: Text(_detailType!.subtitle ?? ''),
        ),
        ListTile(
          title: const Text('财务分析包含该项'),
          trailing: _detailType!.analysisIncluded == true
              ? const Chip(
                  padding: EdgeInsets.all(0.0),
                  label: Text('包含'),
                  backgroundColor: Colors.lightGreenAccent,
                )
              : const Chip(
                  padding: EdgeInsets.all(0.0),
                  label: Text('不包含'),
                  backgroundColor: Colors.orangeAccent,
                ),
        ),
        const Divider(),
        const ListCaption('操作记录'),
        ActionLogView(_detailType!),
      ],
    );
  }

  /// Gets current authenticated user.
  Future<void> _getCurrentUser() async {
    final user = await AuthStateService.instance.currentUser;

    if (mounted) {
      setState(() => _user = user);
    }
  }

  /// Deletes current detail.
  void _delete() {
    showConfirmDialog(
      context,
      '删除类别 ${_detailType!.title}？',
      onConfirm: () async {
        showInProgressOverlay(context);

        // Deletes item on back server.
        final deleted = await _detailTypeService.delete(
          _detailType!.incomeExpenseType!,
          _detailType!.name!,
        );

        // DO NOT use BuildContext across asynchronous gaps.
        // https://dart-lang.github.io/linter/lints/use_build_context_synchronously.html
        if (mounted) {
          // Closes progress overlay.
          NavigatorHelper.pop(context);
        }

        if (deleted) {
          // DO NOT use BuildContext across asynchronous gaps.
          // https://dart-lang.github.io/linter/lints/use_build_context_synchronously.html
          if (mounted) {
            // Pops detail view and notifies last page.
            NavigatorHelper.pop(context, _detailType!.id);
          }
        } else {
          showToast('类别 ${_detailType!.title} 已被使用，不可删除。');
        }
      },
    );
  }

  /// Goes to detail update view.
  Future<void> _gotoUpdateView() async {
    // Takes current result that if the data has been updated.
    final updatedData = await NavigatorHelper.push<IncomeExpenseDetailType>(
      context,
      EditIncomeExpenseDetailType(_detailType!),
    );

    // If [updatedData] is not null that means the data already has been updated.
    // Even user goes to the edit view and pops again without any change.
    // That's why we only need to change [_updatedDetailType] value when [updatedData] is not null.
    //
    // Example:
    // 1. Goes to edit view, makes change and pops. Edit view returns updated data.
    // 2. Goes to edit view again, makes NO change and pops. Edit view returns null.
    // 3. Goes to edit view makes change again. Edit view returns new updated data.
    // 4. We need to pass the updated data to parent view anyway.
    if (updatedData != null) {
      _updatedDetailType = updatedData;
    }

    // Only when current result indicates the data has been changed then we need to refresh the data.
    if (updatedData != null) {
      if (mounted) {
        setState(() => _detailType = updatedData);
      }
    }
  }

  void _onPopInvokedWithResult(bool didPop, dynamic result) {
    if (didPop) {
      return;
    }

    NavigatorHelper.pop(context, _updatedDetailType);
  }
}
